#include "DetailTipsData.h"
#include <qbprotocol/include/SSQBModel.h>
#include <core/Utility.h>
#include <core/sharedata/login_data.h>
#include <bondlib/BondContainer.h>
#include <bondlib/AdditionBondInfo.h>

static void makeTipsReq(qb::proto::Message& msg, qb::SSRequestMsg* req)
{
	qb::proto::Message::List sublist;
	BondSSInfoNewReq_t* pdata = (BondSSInfoNewReq_t*)req->m_pRequest;
	for (std::list<TW_BOND>::const_iterator it = pdata->m_Bond.begin();
		it != pdata->m_Bond.end(); ++it)
	{
		qb::proto::VariantMap listmsg;
		listmsg.setString("Bond_Type", it->m_Bond_Type);
		listmsg.setString("BondID", it->m_BondID);
		listmsg.setString("BondKey", it->m_BondKey);
		listmsg.setString("ListedMarket", it->m_ListedMarket);
		sublist.push_back(listmsg);
	}
	qb::proto::VariantMap submsg;
	submsg.SetList("Bond", sublist);
	msg.SetMap("xBondSSInfoNewReq", submsg);
}

DetailTipsData::DetailTipsData(QObject* parent)
	: QObject(parent)
{

}

DetailTipsData::~DetailTipsData()
{
	for (auto iter = m_data.begin(); iter != m_data.end(); ++iter)
	{
		for (auto iter2 = iter->second.begin(); iter2 != iter->second.end(); ++iter2)
		{
			if (iter2->first == detailModel_BondDetail)
				delete static_cast<xBondSSInfoNew_c*>(iter2->second);
			else if(iter2->first == detailModel_PublisherBasic)
				delete static_cast<xBondIssuerInfo_c*>(iter2->second);
		}
	}

	m_data.clear();
}

void* DetailTipsData::getData(const std::string& bondkey, TipsDataType type)
{
	int index = CBondContainer::instance().GetBondIndex(bondkey);
	if (index < 0)
		return nullptr;
	const CBondInfo& bi = CBondContainer::instance().ElementAtR(index);
	if (!bi.IsValidBond())
		return nullptr;

	std::string key = bondkey;
	if (type == detailModel_PublisherBasic)
		key = bi.GetIssuerCode();

	std::lock_guard<std::mutex> locker(m_mutex);
	auto iter = m_data[key].find(type);
	if (iter != m_data[key].end() && iter->second)
		return iter->second;
	else
		m_data[key][type] = nullptr;

	reqData(bi, type);

	return nullptr;
}

void DetailTipsData::onDataArrived(const qb::SSAckMsg& msg)
{
	if (msg.m_FuncID == E_FID_QB_BOND_SS_INFO_NEW)
	{
		xQBBondSSInfoNewListAck_c* infoList = static_cast<xQBBondSSInfoNewListAck_c*>(msg.m_pRet);
		if (!infoList)
			return;

		for (auto info : infoList->m_List)
		{
			int bondIndex = CBondContainer::instance().GetBondIndex(info.m_BondKey, info.m_BondListed_Market);
			if (!CBondContainer::instance().IsValidIndex(bondIndex))continue;
			const CBondInfo& bi = CBondContainer::instance().ElementAtR(bondIndex);

			std::string bondComKey = bi.GetCombBondKey();
			xBondSSInfoNew_c* ptr = nullptr;
			auto iter = m_data[bondComKey].find(detailModel_BondDetail);
			if (iter != m_data[bondComKey].end() && iter->second)
				ptr = static_cast<xBondSSInfoNew_c*>(iter->second);
			else
			{
				ptr = new xBondSSInfoNew_c();
				m_data[bondComKey][detailModel_BondDetail] = ptr;
			}
			*ptr = info;
			emit dataArrived(bondComKey.c_str(), detailModel_BondDetail);
		}
	}
	else if(msg.m_FuncID == E_FID_QB_BOND_SS_ISSUER_INFO_NEW)
	{
		xBondIssuerInfo_c* xInfo = static_cast<xBondIssuerInfo_c*>(msg.m_pRet);
		if (!xInfo)
			return;

		int bondIndex = CBondContainer::instance().GetBondIndex(xInfo->m_BondKey, xInfo->m_Listed_Market);
		if (!CBondContainer::instance().IsValidIndex(bondIndex))return;
		const CBondInfo& bi = CBondContainer::instance().ElementAtR(bondIndex);

		const char* issueCode = bi.GetIssuerCode();
		for (auto& data : m_data)
		{
			if(strcmp(data.first.c_str(), issueCode) != 0)
				continue;

			xBondIssuerInfo_c* ii = nullptr;
			auto iter = data.second.find(detailModel_PublisherBasic);
			if (iter != data.second.end() && iter->second)
				ii = static_cast<xBondIssuerInfo_c*>(iter->second);
			else
			{
				ii = new xBondIssuerInfo_c();
				data.second[detailModel_PublisherBasic] = ii;
			}
			*ii = *xInfo;
			emit dataArrived(bi.GetCombBondKey(), detailModel_PublisherBasic);
			break;
		}

	}
}

void DetailTipsData::reqData(const CBondInfo& bi, TipsDataType type)
{
	TW_BOND bond;
	FIELDCOPY(bond.m_BondKey, bi.GetBondKey());
	FIELDCOPY(bond.m_ListedMarket, bi.GetListedMarket());

	if (type == detailModel_BondDetail)
	{
		qb::SSRequestMsg msg;
		msg.m_FuncID = E_FID_QB_BOND_SS_INFO_NEW;
		BondSSInfoNewReq_t stReq;
		stReq.m_Bond.push_back(bond);
		msg.m_pRequest = &stReq;

		MessagePoster poster(&msg, &makeTipsReq);
		poster.send(this);
	}
	else if (type == detailModel_PublisherBasic)
	{
		BondSSInfoNewReq_t stReqPb;
		if (bi.IsAddIssueBond()) {
			CAdditionBondInfo* addInfo = const_cast<CAdditionBondInfo*>(bi.GetAdditionInfo());
			std::string key = addInfo->GetFirstIssueKey();
			key = key.substr(0, key.length() - 4);
			FIELDCOPY(bond.m_BondKey, key.c_str());
		}
		stReqPb.m_Bond.push_back(bond);

		qb::SSRequestMsg msg;
		msg.m_FuncID = E_FID_QB_BOND_SS_ISSUER_INFO_NEW;
		msg.m_pRequest = &stReqPb;
		MessagePoster poster(&msg, &makeTipsReq);
		poster.send(this);
	}
}
